package com.insmess.speech.websocket;

import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@ServerEndpoint("/asr/stream")
@Component
@Slf4j
public class AsrStreamSocket {

    private Session session;

    private WebSocketClient webSocketClient;

    private String fileName;
    private static Environment env;

    @Autowired
    private void setEnvironment(Environment env) {
        AsrStreamSocket.env = env;
    }

    @SneakyThrows
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        session.setMaxBinaryMessageBufferSize(1024 * 1024);
        log.info("与SessionId：{}建立连接", session.getId());
        //初始化websocket客户端
        initWebSocketClient(session);
    }

    @SneakyThrows
    private void initWebSocketClient(Session session) {
        String url = env.getProperty("speech-server.stream-url");
        URI uri = new URI(url + "/paddlespeech/asr/streaming");
        this.fileName = UUID.randomUUID() + ".wav";
        String fileName = this.fileName;
        this.webSocketClient = new WebSocketClient(uri) {
            @SneakyThrows
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                Map<String, Object> map = new HashMap<>();
                map.put("name", fileName);
                map.put("signal", "start");
                map.put("nbest", 1);
                String json = JSONUtil.toJsonStr(map);
                send(json);
            }

            @SneakyThrows
            @Override
            public void onMessage(String message) {
                session.getBasicRemote().sendText(message);
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                System.out.println("连接已关闭");
            }

            @Override
            public void onError(Exception ex) {
                ex.printStackTrace();
            }
        };
        this.webSocketClient.connect();
    }

    @OnClose
    public void onClose() {
        Map<String, Object> map = new HashMap<>();
        map.put("name", this.fileName);
        map.put("signal", "end");
        map.put("nbest", 1);
        //发送销毁通知
        this.webSocketClient.send(JSONUtil.toJsonStr(map));
        this.webSocketClient.close();
    }

    @OnMessage
    public void onMessage(byte[] bArr, Session session) {
        log.debug("接收：{}", Arrays.toString(bArr));
//        System.out.println(this.webSocketClient.getReadyState());
        webSocketClient.send(bArr);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("Session:{}的WebSocket发生错误", session.getId(), error);
    }

    public Session getSession() {
        return session;
    }

    public String getSessionId() {
        return session.getId();
    }
}
